import React, { Component } from 'react'
import { flushSync } from 'react-dom'
// flushSync 它会影响性能，不是太推荐使用，除非在一些特殊场景要求下才用
// 它有点类似于 vue中的nextTick，setState在它里面会立刻去更新
// flushSync(()=>{})

// state它是在类组件中定义数据的
// 此成员属性直接修改它是不会通知视图更新，而是要通过指定的方法 this.setState来完成修改数据才能更新视图
// state定义时为一个对象
// state它里面定义的数据没有进行代理，所以在获取时要通过正常的成员属性方式来获取  this.state.xx
// 更新视图的方法
//  + this.forceUpdate  强制更新，不会进行diff比对
//  + this.setState     先比对新旧节点中的数据和属性然后进行是否要更新
// -------------------
// react17及之前 this.setState 它是同步也是异步
//  + 在合成事件中为异步 onClick(){this.setState()}
//  + 在原生事件或宏任务或微任务中为同步  settimeout(()=>{this.setState()})
// react18之后 this.setState都为异步 -- 提升性能
// ---- 语法
// + 对象 一般用于直接设置值，不关心原值，直接设置新值
//    this.setState({key:value},()=>{获取修改后它的state中的数据最新值})
// + 回调函数  一般用于在原值的基础上进行设置值  (推荐)
//    this.setState(state=>({key:value}),()=>{获取修改后它的state中的数据最新值})

class App extends Component {
  // 推荐
  state = {
    count: 100
  }

  setCount = () => {
    // 直接修改state成员属性中的属性值,只会修改数据不会更新视图
    // 更新数据它几乎不会影响到性能，更新视图会对性能有影响
    // this.state.count++
    // console.log(this.state.count)
    // 修改state里面数据的同时，让视图更新 this.setState
    // 对象 参数2可选
    // this.setState({ count: Date.now() }, () => {
    //   console.log(this.state.count)
    // })
    // this.setState({ count: Date.now() })
    // 103
    // this.setState({ count: this.state.count + 1 })
    // this.setState({ count: this.state.count + 2 })
    // this.setState({ count: this.state.count + 3 })

    // 106
    flushSync(() => {
      this.setState({ count: this.state.count + 1 })
    })
    flushSync(() => {
      this.setState({ count: this.state.count + 2 })
    })
    flushSync(() => {
      this.setState({ count: this.state.count + 3 })
    })

    // 回调函数 106
    //   this.setState((state) => {
    //     return {
    //       count: state.count + 1
    //     }
    //   })
    //   this.setState((state) => ({ count: state.count + 2 }))
    //   this.setState((state) => ({ count: state.count + 3 }))
  }

  render() {
    console.log('render')
    const { count } = this.state
    return (
      <div>
        <h3>count：{count}</h3>
        <button onClick={this.setCount}>++修改count++</button>
      </div>
    )
  }
}

export default App
